-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Fix rgb565 / bgr565 interchange issue in Zephyr display #79996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix rgb565 / bgr565 interchange issue in Zephyr display #79996
Conversation
@danieldegrasse : The display format is RGB565, not BGR565. I think there are two mistakes that makes it "works" in practice for NXP display, but make it confused for others, and that impacts the video capture where we forced RGB565 to BGR565 for display.
|
Taking the example of RK055HDMIPI4MA01: I did not test on hardware though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Zephyr's definition of BGR_565 is unfortunately rather odd- BGR_565 corresponds to what most definitions consider RGB565, and RGB_565 corresponds to BGR_565, but byte swapped.
The only reason I can imagine we did this was that most SPI displays that use 16 bit color would use the RGB_565 format, since the byte swap would result on the data on the SPI MOSI line being in the correct order.
This comment by @zejiang0jason does a good job explaining what is going on here: #71406 (comment)
Another way to check this would be to run samples/drivers/display
with this PR, you'll see that the box we expect to be gray is instead cycling through a set of incorrect colors.
@danieldegrasse : I did check with both |
I will look through Jason's explaination but honestly, I can't understand where and how Zephyr define a RGB565 to become BGR565. If it's an issue with only NXP's displays, it should not be enforced widely in Zephyr. |
Oh, just retested. Indeed, with the display sample, the colors are wrong, from top-left to bottom-left the box colors are : R -> B, G -> R, B -> G and the grey box cycling through a set of incorrect colors as you said, sorry for that (I am not too familiar with the display sample, so I didn't check carefully). But for the video capture sample, the color bar pattern are all correct how do we explain that ? |
fc4ecc7
to
a39d1ca
Compare
So this is where I fundamentally disagree- what this PR is doing is swapping the meaning of two constants in Zephyr. From my POV that means we should swap all usages of those constants in tree, so if a display is broken it stays broken and if a display is working it continues to work. Why would we knowingly create breakage in displays (which this PR will do), versus keeping things working as they are. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry but my change request still stands. I do not think the right way to make this change is to "swap things and find out what breaks". We know what will break, we are swapping the meaning of two constants. Swap the usages of the constants in tree and things won't break.
I'm not a maintainer here (nor is there a display maintainer)- I would like to hear the opinion of another collaborator in displays on this change though. @VynDragon, @jfischer-no, @JarmouniA, any thoughts? If others disagree with me I'll happily remove my block- maybe there is something I'm missing here
Sorry but I disagree here too. In fact, we don't know which will break unless we test all the displays (which will be difficult). The assumption that all the in-tree displays are based on the display sample for validation and needs a swap is strong but I am sure that not all of them (LTDC is an example and some other boards and display drivers I see still consider RGB565 is RGB565 and BGR565 is BGR565 so no reason to swap them). |
@danieldegrasse thank you for the prompt reply. I did not intend to bypass your comment and it seems I misinterpreted your latest message as for confirmation as it was intermediate step only. Should the milestone be moved to 4.3.0 or is this considered a bugfix that can land after the feature-freeze? |
No worries! Personally I'd rather see it go in on 4.3.0- I know the naming of the constants is confusing as is (and I'd like to see them changed) but I don't see the naming as a bug |
@danieldegrasse what is the definition of "working/not working"? I think the root question is whether there is agreement here on if these defines are correct or not? If they are incorrect then we should fix them instead of maintaining an incorrect implementation/usage. If that results in other displays behaving incorrectly they can be fixed. |
The defines are not in alignment with what other projects use- so IMO yes, they are incorrect. However they do work, they just should be changed. Personally I feel this is somewhat similar to a documentation issue, IE something that isn't breaking anyone's use of Zephyr right now. My concern with making the change close to release is that it is difficult to test all displays (as @ngphibang pointed out). IMO the way to make this change is to swap all usages in tree and do it earlier in the release cycle, so that users have some time to notice any issues we might not have anticipated. Swapping all usages (IMO) is lower risk than making the change knowing it will break some displays, but it still isn't zero risk |
Well the PR has been posted since October of last year ;-). But if you are okay, maybe we schedule this to be merged right after the v4.2 release. Then that would allow the next release cycle for users to identify and address any additional displays that need to be changed. |
When we say "it works", it mean to work only in the world of the display sample. It's a burden to take care of whenver we do RGB565 or BGR565 outside of the display sample or when we go from and to the display domain, e.g. when developing a new multimedia library. I am okay to let it be till 4.3, or more but I think I will not blindly swap RGB formats for all the in-tree displays without testing it or at least someone helps to point out that it works / breaks on a display. |
@ngphibang I agree, that was my experience when testing many STM32 boards with displays. To me, what is in this PR rn is the correct way forward, but it should be merged in the next release to leave room for potential fixes and more testing.
@danieldegrasse I disagree, in my experience when I was testing displays with the sample, I was not paying attention to colors, I noticed the weird flicking of the grey box, but ignored it (similar to what @avolmat-st described), LVGL samples were the way I would actually validate colors and other things... |
Hmm ok- thank you for the alternate perspective here. Maybe more displays than I think have this issue. Perhaps when we merge this PR we add a note to the display sample stating what an incorrect color definition looks like? I'm going to clear my block then, but I agree- I would really rather hold this until the next release and correct displays over a release cycle |
Consensus is that current approach is the best way forwards- not going to stand in the way of getting this fixed
i dont think it should be swapped in the sample... Higher chances displays match the current sample correctly than they dont. |
@danieldegrasse Is there a possibility that this PR is merged for v4.2.0.RC2 ? |
Wouldn't it be possible to fix the STM32 display driver by aligning it with the (backwards) way that Zephyr currently reports display formats? IE something like the following change: diff --git a/drivers/display/display_stm32_ltdc.c b/drivers/display/display_stm32_ltdc.c
index b34975f8c58..cdd0c63bae3 100644
--- a/drivers/display/display_stm32_ltdc.c
+++ b/drivers/display/display_stm32_ltdc.c
@@ -55,7 +55,7 @@ LOG_MODULE_REGISTER(display_stm32_ltdc, CONFIG_DISPLAY_LOG_LEVEL);
#elif CONFIG_STM32_LTDC_RGB565
#define STM32_LTDC_INIT_PIXEL_SIZE 2u
#define STM32_LTDC_INIT_PIXEL_FORMAT LTDC_PIXEL_FORMAT_RGB565
-#define DISPLAY_INIT_PIXEL_FORMAT PIXEL_FORMAT_RGB_565
+#define DISPLAY_INIT_PIXEL_FORMAT PIXEL_FORMAT_BGR_565
#else
#error "Invalid LTDC pixel format chosen"
#endif
@@ -110,9 +110,9 @@ static int stm32_ltdc_set_pixel_format(const struct device *dev,
struct display_stm32_ltdc_data *data = dev->data;
switch (format) {
- case PIXEL_FORMAT_RGB_565:
+ case PIXEL_FORMAT_BGR_565:
err = HAL_LTDC_SetPixelFormat(&data->hltdc, LTDC_PIXEL_FORMAT_RGB565, 0);
- data->current_pixel_format = PIXEL_FORMAT_RGB_565;
+ data->current_pixel_format = PIXEL_FORMAT_BGR_565;
data->current_pixel_size = 2u;
break;
case PIXEL_FORMAT_RGB_888:
@@ -158,7 +158,7 @@ static void stm32_ltdc_get_capabilities(const struct device *dev,
data->hltdc.LayerCfg[0].WindowY0;
capabilities->supported_pixel_formats = PIXEL_FORMAT_ARGB_8888 |
PIXEL_FORMAT_RGB_888 |
- PIXEL_FORMAT_RGB_565;
+ PIXEL_FORMAT_BGR_565;
capabilities->screen_info = 0; This aligns with the way the NXP LCDIF currently reports display pixel formats, and I believe that display works with the video sample (although I lack hardware to test) |
Hi @VynDragon, Thank you for the double check of the ssd1351 display. I couldn't find an in-tree device tree that uses this display so I suppose you tested on an out-of-tree board ? Maybe there is a chance that the RGB color is already swapped, i.e. But I believe this is not the case. So, could you help to fill the Up to now, we know that there is at least 1 display "need to be fixed / swapped" after the PR merged ( So, as you also pointed out, there is no painless solution. The benefit of this PR is that we will have a consistent defines for RGB565 / BGR565 across Zephyr's subsystems, e.g. video, display, and which is also compliant with most of other projects, especially the Linux kernel https://www.kernel.org/doc/html/v6.11/userspace-api/media/v4l/pixfmt-rgb.html PS:
Consensus is that we do not swap all of them. We will fix / swap displays / boards that need to be, like the ssd1351. |
At best i can tell zephyr 'RGB565' is the same as linux RGB565 In fact it all seems to agree with the zephyr RGB565.... |
Well, what you call "zephyr" is actually the display sample, which is "fixed" by the PR. In the very first comments and in the commits, it is shown that a SW generator, a camera sensor that outputs RGB565 display wrong colors on a eLCDIF display that supports RGB565. |
Linux at https://www.kernel.org/doc/html/v6.11/userspace-api/media/v4l/pixfmt-rgb.html mentions little-endian, are you sure it is not because that is swapped around between the camera and the display? EG this: #79996 (comment) works in the opposite way, EG, on linux: RGB565 in
BGR565 in
|
Degrass said the samples defines what it is for zephyr. |
This is opposite with what we found and comments above #79996 (comment)
About "the display sample" defines what it is for Zephyr, including the video, I have no idea. |
NVM about this discussion, it is inverted in LVGL in practice, so I dont understand why, but you are right. Maybe one thing of note is that I need to both invert RGB565 order AND use CONFIG_LV_COLOR_16_SWAP to get the right output with LVGL. |
Hi @danieldegrasse, yes I confirm that with such modification done the LTDC driver, this allows to make the video sample work with the LTDC as well as the display sample giving the right colors when displayed via the LTDC. |
Absolutely- this is what I'd prefer. A narrow patch like what I described to fix the LTDC driver now for 4.2, and post 4.2 we will get this PR merged. |
PR #92483 pushed |
There is a wrong assumption about the "byte swap" in Zephyr display that makes RGB565 and BGR565 formats are used interchangeably.
This mistake (perhaps) originally comes frome the display samples that leads to the confusion in display drivers, shields, video sample. This PR fixes it.